From 0eecf73be6e7304f382dd16491cd2917f5135bae Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Fri, 13 Feb 2009 09:43:06 +0000 Subject: [PATCH] hvm: Align periodic vpts. Aligned periodic vpts can improve the HVM guest power consumption a lot, especially while the guest using high HZ such as 1000HZ. Signed-off-by: Wei Gang --- tools/python/xen/xend/XendConfig.py | 3 +++ tools/python/xen/xend/XendConstants.py | 1 + tools/python/xen/xend/XendDomainInfo.py | 6 ++++++ tools/python/xen/xm/create.py | 7 ++++++- tools/python/xen/xm/xenapi_create.py | 1 + xen/arch/x86/hvm/hvm.c | 1 + xen/arch/x86/hvm/vpt.c | 10 ++++++++-- xen/common/timer.c | 7 +++++++ xen/include/public/hvm/params.h | 5 ++++- xen/include/xen/timer.h | 3 +++ 10 files changed, 40 insertions(+), 4 deletions(-) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index 4b30c1ae43..2d2138559b 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -158,6 +158,7 @@ XENAPI_PLATFORM_CFG_TYPES = { 'vncdisplay': int, 'vnclisten': str, 'timer_mode': int, + 'vpt_align': int, 'viridian': int, 'vncpasswd': str, 'vncunused': int, @@ -459,6 +460,8 @@ class XendConfig(dict): self['platform']['rtc_timeoffset'] = 0 if 'hpet' not in self['platform']: self['platform']['hpet'] = 0 + if 'vpt_align' not in self['platform']: + self['platform']['vpt_align'] = 1 if 'loader' not in self['platform']: # Old configs may have hvmloader set as PV_kernel param if self.has_key('PV_kernel') and self['PV_kernel'] != '': diff --git a/tools/python/xen/xend/XendConstants.py b/tools/python/xen/xend/XendConstants.py index 13e046a086..3130f75c08 100644 --- a/tools/python/xen/xend/XendConstants.py +++ b/tools/python/xen/xend/XendConstants.py @@ -50,6 +50,7 @@ HVM_PARAM_VIRIDIAN = 9 # x86 HVM_PARAM_TIMER_MODE = 10 HVM_PARAM_HPET_ENABLED = 11 HVM_PARAM_ACPI_S_STATE = 14 +HVM_PARAM_VPT_ALIGN = 16 restart_modes = [ "restart", diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 5c08992963..b56d3c55ef 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -2237,6 +2237,12 @@ class XendDomainInfo: xc.hvm_set_param(self.domid, HVM_PARAM_HPET_ENABLED, long(hpet)) + # Optionally enable periodic vpt aligning + vpt_align = self.info["platform"].get("vpt_align") + if hvm and vpt_align is not None: + xc.hvm_set_param(self.domid, HVM_PARAM_VPT_ALIGN, + long(vpt_align)) + # Set maximum number of vcpus in domain xc.domain_max_vcpus(self.domid, int(self.info['VCPUs_max'])) diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index f87f5ccc53..d1a8ca2e0c 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -219,6 +219,10 @@ gopts.var('timer_mode', val='TIMER_MODE', use="""Timer mode (0=delay virtual time when ticks are missed; 1=virtual time is always wallclock time.""") +gopts.var('vpt_align', val='VPT_ALIGN', + fn=set_int, default=1, + use="Enable aligning all periodic vpt to reduce timer interrupts.") + gopts.var('viridian', val='VIRIDIAN', fn=set_int, default=0, use="""Expose Viridian interface to x86 HVM guest? @@ -891,7 +895,8 @@ def configure_hvm(config_image, vals): 'sdl', 'display', 'xauthority', 'rtc_timeoffset', 'monitor', 'acpi', 'apic', 'usb', 'usbdevice', 'keymap', 'pci', 'hpet', 'guest_os_type', 'hap', 'opengl', 'cpuid', 'cpuid_check', - 'viridian', 'xen_extended_power_mgmt', 'pci_msitranslate' ] + 'viridian', 'xen_extended_power_mgmt', 'pci_msitranslate', + 'vpt_align' ] for a in args: if a in vals.__dict__ and vals.__dict__[a] is not None: diff --git a/tools/python/xen/xm/xenapi_create.py b/tools/python/xen/xm/xenapi_create.py index 39489e497f..74a534f58c 100644 --- a/tools/python/xen/xm/xenapi_create.py +++ b/tools/python/xen/xm/xenapi_create.py @@ -1037,6 +1037,7 @@ class sxp2xml: 'usbdevice', 'hpet', 'timer_mode', + 'vpt_align', 'viridian', 'vhpt', 'guest_os_type', diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index ae4acb3787..517dbb33e8 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -311,6 +311,7 @@ int hvm_domain_initialise(struct domain *d) hvm_init_guest_time(d); d->arch.hvm_domain.params[HVM_PARAM_HPET_ENABLED] = 1; + d->arch.hvm_domain.params[HVM_PARAM_VPT_ALIGN] = 1; hvm_init_cacheattr_region_list(d); diff --git a/xen/arch/x86/hvm/vpt.c b/xen/arch/x86/hvm/vpt.c index 5dae7cd505..33f2400a0e 100644 --- a/xen/arch/x86/hvm/vpt.c +++ b/xen/arch/x86/hvm/vpt.c @@ -389,8 +389,14 @@ void create_periodic_time( * LAPIC ticks for process accounting can see long sequences of process * ticks incorrectly accounted to interrupt processing. */ - if ( !pt->one_shot && (pt->source == PTSRC_lapic) ) - pt->scheduled += delta >> 1; + if ( !pt->one_shot ) + { + if ( v->domain->arch.hvm_domain.params[HVM_PARAM_VPT_ALIGN] ) + pt->scheduled = align_timer(pt->scheduled, pt->period); + else if ( pt->source == PTSRC_lapic ) + pt->scheduled += delta >> 1; + } + pt->cb = cb; pt->priv = data; diff --git a/xen/common/timer.c b/xen/common/timer.c index d5f08d370f..eca25b3fb7 100644 --- a/xen/common/timer.c +++ b/xen/common/timer.c @@ -473,6 +473,13 @@ void process_pending_timers(void) timer_softirq_action(); } +s_time_t align_timer(s_time_t firsttick, uint64_t period) +{ + if ( !period ) + return firsttick; + + return firsttick + (period - 1) - ((firsttick - 1) % period); +} static void dump_timerq(unsigned char key) { diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h index d5511bdd0a..15d828fe14 100644 --- a/xen/include/public/hvm/params.h +++ b/xen/include/public/hvm/params.h @@ -103,6 +103,9 @@ /* TSS used on Intel when CR0.PE=0. */ #define HVM_PARAM_VM86_TSS 15 -#define HVM_NR_PARAMS 16 +/* Boolean: Enable aligning all periodic vpts to reduce interrupts */ +#define HVM_PARAM_VPT_ALIGN 16 + +#define HVM_NR_PARAMS 17 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ diff --git a/xen/include/xen/timer.h b/xen/include/xen/timer.h index f3d2705d82..0379d950a3 100644 --- a/xen/include/xen/timer.h +++ b/xen/include/xen/timer.h @@ -122,6 +122,9 @@ DECLARE_PER_CPU(s_time_t, timer_deadline); /* Arch-defined function to reprogram timer hardware for new deadline. */ extern int reprogram_timer(s_time_t timeout); +/* calculate the aligned first tick time for a given periodic timer */ +extern s_time_t align_timer(s_time_t firsttick, uint64_t period); + #endif /* _TIMER_H_ */ /* -- 2.30.2